using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.UI;
using Smarly.Bussines.Model.Account;
using Smarly.Core;

namespace Smarly.Bussines.Membership
{
	public class SmarlyPrincipal : IPrincipal
	{
		static List<SmarlyRole> _smarlyRoles;
		static SmarlyPrincipal()
		{
			_smarlyRoles = SmarlyRole.GetList();
		}

		public SmarlyPrincipal(HttpRequestBase request, HttpResponseBase response, List<string> spUpdates = null)
		{
			var cookie = request.Cookies[".auth"];
			if (cookie == null)
			{
				Identity = new SmarlyIdentity(false);
			}
			else
			{
				Pair ticket = null;

				try
				{
					var temp = Serializer.Serialize<Pair>(SmarlyCryptography.DecryptString(cookie.Value));

					if (temp.First is string && temp.Second is string)
						ticket = temp;
				}
				catch (Exception)
				{
					ticket = null;
				}

				if (ticket == null)
				{
					Identity = new SmarlyIdentity(false);
					response.LogOut(request);
					return;
				}

				Login l = new Login() { Email = (string)ticket.First, HashCode = (string)ticket.Second, SpUpdates = spUpdates }.ChechHash();

				_roles = l.Roles;

				if (!string.IsNullOrWhiteSpace(l.HashCode))
				{
					Identity = new SmarlyIdentity(true, l.Email, l.IsIdentify) { UserId = l.UserId, PreviewCount = l.PreviewCount, IsSubscriber = l.IsSubscriber };
				}
				else
				{
					Identity = new SmarlyIdentity(false);
					response.LogOut(request);
				}
			}
		}

		private readonly List<string> _roles;
		#region Implementation of IPrincipal

		public bool IsInRole(string role)
		{
			return _roles != null && _roles.Any(x => x.ToLower() == role.ToLower());
		}

		public IIdentity Identity { get; private set; }

		#endregion

		public bool AllowChanges(string hashTag)
		{
			if (!Identity.IsAuthenticated)
				return false;

			if (IsInRole("Admin"))
				return true;

			if (IsInRole("Editor"))
			{
				var identity = (SmarlyIdentity)Identity;
				return new Editor() { HashTag = hashTag }.AllowEdit(identity).Allow;
			}

			return false;

		}

		public List<string> GetUserRoles()
		{
			List<string> result = _smarlyRoles.OrderByDescending(x => x.Weigth).Where(x => IsInRole(x.Name)).Select(x => x.Name).ToList();

			if (Identity.IsAuthenticated)
				result.Add("User");

			return result;
		}
	}
}